import pandas as pd
import numpy as np
'''
电影评分数据集（UserID，MovieID，Rating，Timestamp）

聚合后单列-单指标统计：每个MovieID的平均评分
df.groupby("MovieID")["Rating"].mean()

聚合后单列-多指标统计：每个MoiveID的最高评分、最低评分、平均评分
df.groupby("MovieID")["Rating"].agg(mean="mean", max="max", min=np.min)
df.groupby("MovieID").agg({"Rating":['mean', 'max', np.min]})

聚合后多列-多指标统计：每个MoiveID的评分人数，最高评分、最低评分、平均评分
df.groupby("MovieID").agg( rating_mean=("Rating", "mean"), user_count=("UserID", lambda x : x.nunique())
df.groupby("MovieID").agg( {"Rating": ['mean', 'min', 'max'], "UserID": lambda x :x.nunique()})
df.groupby("MovieID").apply( lambda x: pd.Series( {"min": x["Rating"].min(), "mean": x["Rating"].mean()}))

记忆：agg(新列名=函数)、agg(新列名=(原列名，函数))、agg({"原列名"：函数/列表})
agg函数的两种形式，等号代表“把结果赋值给新列”，字典/元组代表“对这个列运用这些函数”
'''
def group_demo():
    df = pd.read_csv(
        "../datas/movielens-1m/ratings.dat",
        sep="::",
        engine='python',
        names="UserID::MovieID::Rating::Timestamp".split("::")
    )
    # 统计 每个电影的 平均分
    print(df.groupby('MovieID')['Rating'].mean())
    # 每个MoiveID的最高评分、最低评分、平均评分
    # 方法1：agg函数传入多个结果列名=函数名形式
    res = df.groupby('MovieID')['Rating'].agg(max=np.max,min=np.min,mean=np.mean)
    print(res)
    # 方法2：agg函数传入字典，key是column名，value是函数列表
    # 每个MoiveID的最高评分、最低评分、平均评分
    res = df.groupby('MovieID').agg({"Rating":[np.max,np.min,np.mean]})
    print(res.head())
    # 聚合后多列-多指标统计
    # 方法1：agg函数传入字典，key是原列名，value是原列名和函数元组
    # 回忆：agg函数的两种形式，等号代表“把结果赋值给新列”，字典/元组代表“对这个列运用这些函数”
    result = df.groupby("MovieID").agg(
        rating_mean=("Rating", "mean"),
        rating_min=("Rating", "min"),
        rating_max=("Rating", "max"),
        user_count=("UserID", lambda x : x.nunique())
    )
    print(result.head())
    # 方法2：agg函数传入字典，key是原列名，value是函数列表
    result = df.groupby("MovieID").agg(
        {
            "Rating": ['mean', 'min', 'max'],
            "UserID": lambda x :x.nunique()
        }
    )
    print(result.head())
    # 方法3：使用groupby之后apply对每个子df单独统计
    result = df.groupby("MovieID").apply(agg_func)
    print(result.head())
def agg_func(df):
    return pd.Series({
        "rating_mean": df["Rating"].mean(),
        "rating_min": df["Rating"].min(),
        "rating_max": df["Rating"].max(),
        "user_count": df["UserID"].nunique()
    })

if __name__ == '__main__':
    group_demo()



